﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using LibPlateAnalysis;
using HCSAnalyzer.Classes.Base_Classes.DataStructures;
using HCSAnalyzer.Classes;

namespace HCSAnalyzer.Forms
{
    public partial class FormForPlateLUT : Form
    {
        cGlobalInfo GlobalInfo;
        double GlobalMax = 1;
        double GlobalMin = 0;
        double LocalMin = 0;
        double LocalMax = 1;

        public FormForPlateLUT(cGlobalInfo GlobalInfo)
        {
            InitializeComponent();
            this.GlobalInfo = GlobalInfo;
        }

        private void numericUpDownGeneralMax_ValueChanged(object sender, EventArgs e)
        {
            if (this.GlobalInfo.CurrentScreening == null) return;
            if (numericUpDownGeneralMax.Value < numericUpDownGeneralMin.Value) numericUpDownGeneralMax.Value = numericUpDownGeneralMin.Value;
            this.GlobalMax = (double)numericUpDownGeneralMax.Value;
            if (this.LocalMax > this.GlobalMax)
            {
                //this.LocalMax = this.GlobalMax;
                //this.labelMax.Text = this.LocalMax.ToString("N3");
                this.SetNewLocalMax(this.GlobalMax);
            }
            else
            {
                //this.GlobalMax = this.LocalMax;
            }

            if (GlobalMax == 0)
                this.trackBarForPlateLUTMax.Value = 0;
            else
            {
                int Value = (int)(((this.GlobalMax - this.LocalMax) * 100) / (this.GlobalMax - this.GlobalMin));
                if((Value>0)&&(Value<=100))
                    this.trackBarForPlateLUTMax.Value = Value;
            }
            UpDatePlateColor();
        }

        private void numericUpDownGeneralMin_ValueChanged_1(object sender, EventArgs e)
        {
            if (this.GlobalInfo.CurrentScreening == null) return;
            if (numericUpDownGeneralMin.Value > numericUpDownGeneralMax.Value) numericUpDownGeneralMin.Value = numericUpDownGeneralMax.Value;
         
            this.GlobalMin = (double)numericUpDownGeneralMin.Value;
            if (this.LocalMin < this.GlobalMin)
            {
                //this.LocalMin = this.GlobalMin;
                //this.labelMin.Text = this.LocalMin.ToString("N3");
                SetNewLocalMin(this.GlobalMin);
            }
            else
            {
              //  this.GlobalMin = this.LocalMin;
            }

            this.labelMin.Text = this.LocalMin.ToString("N3");

            //double Res= Math.Ceiling(this.GlobalMin);
            if (GlobalMin == 0)
                this.trackBarForPlateLUTMin.Value = 0;
            else
            {
                int Value = (int)(((this.LocalMin - this.GlobalMin) * 100) / (this.GlobalMax - this.GlobalMin));
                if ((Value > 0) && (Value <= 100))
                    this.trackBarForPlateLUTMin.Value = Value;
            }

            UpDatePlateColor();
        }

        private void UpDatePlateColor()
        {
            if (this.GlobalInfo.CurrentScreening == null) return;
            if (this.GlobalInfo.IsDisplayClassOnly) return;

            cPlate CurrentPlate = this.GlobalInfo.CurrentScreening.GetCurrentDisplayPlate();
            cDescriptorType cDT = this.GlobalInfo.CurrentScreening.ListDescriptors.GetActiveDescriptor();
            cLUT MyLUT = new cLUT();

            byte[][] LUT = MyLUT.LUT_JET;

            int ConvertedValue = 0;
            Color WellColor = Color.Transparent;
            foreach (cWell CurrentWell in CurrentPlate.ListActiveWells)
            {
                if (CurrentWell != null)
                {
                    if (this.LocalMin == this.LocalMax)
                    {
                        WellColor = Color.FromArgb(LUT[0][0], LUT[1][0], LUT[2][0]);
                    }
                    else
                    {
                        double Val = CurrentWell.GetAverageValue(cDT);

                        ConvertedValue = (int)(((Val - this.LocalMin) * (LUT[0].Length - 1)) / (this.LocalMax - this.LocalMin));
                        if(ConvertedValue >= LUT[0].Length)
                            WellColor = Color.FromArgb(LUT[0][LUT[0].Length - 1], LUT[1][LUT[0].Length - 1], LUT[2][LUT[0].Length - 1]);
                        else if (ConvertedValue<0)
                            WellColor = Color.FromArgb(LUT[0][0], LUT[1][0], LUT[2][0]);
                        else 
                            WellColor = Color.FromArgb(LUT[0][ConvertedValue], LUT[1][ConvertedValue], LUT[2][ConvertedValue]);
                    }
                    CurrentWell.SetNewColor(WellColor);
                }
            }
        }

        void SetNewLocalMax(double LocalMax)
        {
            if (GlobalMax < GlobalMin) return;

            this.LocalMax = LocalMax;
            this.labelMax.Text = this.LocalMax.ToString("N3");

            if (this.GlobalMax == 0)
                this.trackBarForPlateLUTMax.Value = 0;
            else
                this.trackBarForPlateLUTMax.Value = (int)((this.LocalMax * 100) / (this.GlobalMax));
        }

        void SetNewLocalMin(double LocalMin)
        {
            if (GlobalMax <= GlobalMin) return;

            this.LocalMin = LocalMin;
            this.labelMin.Text = this.LocalMin.ToString("N3");

            // compute new slider position
            this.trackBarForPlateLUTMin.Value = (int)(((this.LocalMin - this.GlobalMin) * 100) / (this.GlobalMax-this.GlobalMin));
        }

        public void RefreshMinMax()
        {
            if (this.GlobalInfo.CurrentScreening == null) return;

            cExtendedTable MinMaxTable = null;

            if (currentPlateOnlyToolStripMenuItem.Checked)
            {
                cPlate CurrentPlate = this.GlobalInfo.CurrentScreening.GetCurrentDisplayPlate();
                cDescriptorType cDT = this.GlobalInfo.CurrentScreening.ListDescriptors.GetActiveDescriptor();
                MinMaxTable = CurrentPlate.GetMinMax(cDT);
            }
            else
            {
                cDescriptorType cDT = this.GlobalInfo.CurrentScreening.ListDescriptors.GetActiveDescriptor();
                MinMaxTable = this.GlobalInfo.CurrentScreening.ListPlatesActive.GetMinMax(cDT);

                //UpDatePlateColor();
            }

            //this.numericUpDownGeneralMin.ValueChanged -= new EventHandler(numericUpDownGeneralMin_ValueChanged_1);
            if (MinMaxTable == null)
            {
                numericUpDownGeneralMax.Value = numericUpDownGeneralMin.Value = 0;
                this.GlobalMin = this.GlobalMax = 0;

                SetNewLocalMin(this.GlobalMin);
                SetNewLocalMax(this.GlobalMax);
            }
            else
            {
                numericUpDownGeneralMin.Value = (decimal)MinMaxTable[0][0];
                this.GlobalMin = MinMaxTable[0][0];

                /*if ((this.GlobalMin > this.LocalMin)||(this.labelMin.Text=="###"))*/
                SetNewLocalMin(this.GlobalMin);
                //this.numericUpDownGeneralMin.ValueChanged += new EventHandler(numericUpDownGeneralMin_ValueChanged_1);

                //this.numericUpDownGeneralMax.ValueChanged -= new EventHandler(numericUpDownGeneralMax_ValueChanged);
                numericUpDownGeneralMax.Value = (decimal)MinMaxTable[0][1];
                this.GlobalMax = MinMaxTable[0][1];
                SetNewLocalMax(this.GlobalMax);
            }
            /*if ((this.GlobalMax < this.LocalMax)||(this.labelMax.Text=="###"))*/ 
            //this.numericUpDownGeneralMax.ValueChanged += new EventHandler(numericUpDownGeneralMax_ValueChanged);

            UpDatePlateColor();


        }

        private void currentPlateOnlyToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RefreshMinMax(); 
           // SetNewLocalMax(this.GlobalMax);
          //  SetNewLocalMin(this.GlobalMin);
        }

        private void refreshToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RefreshMinMax();
           // SetNewLocalMax(this.GlobalMax);
           // SetNewLocalMin(this.GlobalMin);

        }

        private void trackBarForPlateLUTMax_ValueChanged(object sender, EventArgs e)
        {
            if (this.GlobalInfo.CurrentScreening == null) return;
            double CurrentValue = (double)numericUpDownGeneralMin.Value + (trackBarForPlateLUTMax.Value / 100.0) * ((double)numericUpDownGeneralMax.Value - (double)numericUpDownGeneralMin.Value);

            labelMax.Text = CurrentValue.ToString("N3");
            this.LocalMax = CurrentValue;

            if (trackBarForPlateLUTMax.Value < trackBarForPlateLUTMin.Value) trackBarForPlateLUTMax.Value = trackBarForPlateLUTMin.Value;
            //   if (trackBarForPlateLUTMin.Value < numericUpDownGeneralMin.Value) trackBarForPlateLUTMin.Value = (int)numericUpDownGeneralMin.Value;
            trackBarForPlateLUTMax.Update();

            UpDatePlateColor();
        }

        private void trackBarForPlateLUTMin_ValueChanged(object sender, EventArgs e)
        {
            if (this.GlobalInfo.CurrentScreening == null) return;
            double CurrentValue = (double)numericUpDownGeneralMin.Value + (trackBarForPlateLUTMin.Value / 100.0) * ((double)numericUpDownGeneralMax.Value - (double)numericUpDownGeneralMin.Value);

            labelMin.Text = CurrentValue.ToString("N3");
            this.LocalMin = CurrentValue;
            if (trackBarForPlateLUTMin.Value > trackBarForPlateLUTMax.Value) trackBarForPlateLUTMin.Value = trackBarForPlateLUTMax.Value;
            //   if (trackBarForPlateLUTMin.Value < numericUpDownGeneralMin.Value) trackBarForPlateLUTMin.Value = (int)numericUpDownGeneralMin.Value;
            trackBarForPlateLUTMin.Update();
            UpDatePlateColor();
        }

    }
}
